<template>
    <div class="container">
        <div id="mapBox" class="map"></div>
        <div class="btns">
            <el-button @click="drawHandle('Point')">点</el-button>
            <el-button @click="drawHandle('LineString')">线</el-button>
            <el-button @click="drawHandle('Circle')">园</el-button>
            <el-button @click="drawHandle('Polygon')">多边形</el-button>
            <el-button @click="drawHandle('Box')">矩形</el-button>
            <!-- "Point" | "LineString" | "LinearRing" | "Polygon" | "MultiPoint" | "MultiLineString" | "MultiPolygon" | "GeometryCollection" | "Circle" -->
        </div>
    </div>
</template>

<script lang="ts" setup>
import { onMounted, ref, toRaw } from 'vue';
import 'ol/ol.css';
import GeoJSON from 'ol/format/GeoJSON';
import { Map, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import { fromLonLat } from 'ol/proj';
import { Select, Modify, Draw, Snap } from 'ol/interaction';
import { Vector as VectorLayer } from 'ol/layer';
import { XYZ, Vector as VectorSource } from 'ol/source';
import { Point, Circle, Polygon, SimpleGeometry } from 'ol/geom';
import { Icon, Stroke, Style, Fill } from 'ol/style';
import { Type } from 'ol/geom/Geometry';
import { click } from 'ol/events/condition';
import { createBox, DrawEvent } from 'ol/interaction/Draw';
import { SelectEvent } from 'ol/interaction/Select';
import { DragBox } from 'ol/interaction';
import { noModifierKeys, platformModifierKeyOnly } from 'ol/events/condition';

const map = ref();
const source = ref();
const layer = ref();
const draw = ref();
const select = ref();
const snap = ref();
const modify = ref();

const style = new Style({
    fill: new Fill({
        color: [255, 0, 0, 0.2]
    }),
    stroke: new Stroke({
        color: '#f00',
        width: 3
    }),
    image: new Icon({
        anchor: [0.5, 1],
        size: [32, 32],
        src: new URL('../../assets/map-point.png', import.meta.url).href
    })
});

const selectStyle = new Style({
    fill: new Fill({
        color: [128, 255, 0, 0.2]
    }),
    stroke: new Stroke({
        color: '#cf0',
        width: 5
    }),
    image: new Icon({
        anchor: [0.5, 1],
        size: [32, 32],
        src: new URL('../../assets/map-point-active.png', import.meta.url).href
    })
});

onMounted(() => {
    initMap();
});

function initMap() {
    map.value = new Map({
        target: 'mapBox',
        view: new View({
            center: [116.397477, 39.908692],
            projection: 'EPSG:4326',
            zoom: 12
        }),
        layers: [
            new TileLayer({
                source: new XYZ({
                    url: `http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7`
                })
            })
        ]
    });

    source.value = new VectorSource({ wrapX: true });
    layer.value = new VectorLayer({
        source: source.value,
        style: style
    });
    map.value.addLayer(layer.value);

    const dragBox = new DragBox({
        condition: platformModifierKeyOnly
        // condition: noModifierKeys, // 鼠标左键框选
    });
    map.value.addInteraction(dragBox);
}

function drawHandle(type: Type | 'Box' = 'Point') {
    console.log(type);
    draw.value = new Draw({
        type: type === 'Box' ? 'Circle' : type,
        geometryFunction: type === 'Box' ? createBox() : undefined, //绘制矩形
        source: source.value
    });
    map.value.addInteraction(draw.value);
    draw.value.on('drawend', (e: DrawEvent) => {
        const point = (
            e.feature.getGeometry() as SimpleGeometry
        ).getFlatCoordinates();
        console.log(point, 'drawend=', e);
        draw.value.setActive(false);
    });

    select.value = new Select({
        style: selectStyle,
        condition: function (e) {
            return click(e);
        }
    });
    select.value.on('select', (e: SelectEvent) => {
        if (e.selected.length > 0) {
            const point = toRaw(
                e.selected[0].getGeometry() as SimpleGeometry
            ).getFlatCoordinates();
            console.log(point, 'select=');
        }
    });
    map.value.addInteraction(select.value);

    snap.value = new Snap({
        source: source.value
    });
    map.value.addInteraction(snap.value);

    modify.value = new Modify({
        source: source.value
    });
    modify.value.on('modifyend', (e) => {
        if (e.features.getLength() > 0) {
            const point = (
                e.features.item(0).getGeometry() as SimpleGeometry
            ).getFlatCoordinates();

            console.log(point, 'modifyend=');
        }
    });
    map.value.addInteraction(modify.value);
}
</script>

<style lang="scss">
.container {
    position: relative;
    .map {
        width: 100%;
        height: 80vh;
    }
    .btns {
        position: absolute;
        top: 10px;
        left: 10px;
    }
}
</style>